package orange.com.openstack.sahara.api;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.List;

import net.minidev.json.JSONObject;
import orange.com.openstack.sahara.data.ClusterTemplate;
import orange.com.openstack.sahara.data.NodeGroup;
import orange.com.openstack.sahara.httpConnection.RestCall;

import com.google.gson.Gson;
import com.jayway.jsonpath.JsonPath;

/**
 * class allowing the interaction with the ClusterTemplates Rest service
 * 
 * @author osvaldo.cocucci@gmail.com
 * 
 */
public class ClusterTemplates {

	String endpoint;
	String tenantId;
	String token;
	Gson gson;

	/**
	 * @param endpoint
	 * @param tenantId
	 * @param token
	 * 
	 *            constructor
	 */
	public ClusterTemplates(String endpoint, String tenantId, String token) {
		gson = new Gson();
		this.endpoint = endpoint;
		this.tenantId = tenantId;
		this.token = token;
	}

	/**
	 * 
	 * This operation returns the list of all Cluster Templates.
	 */
	public List<ClusterTemplate> listClusterTemplate() {
		List<ClusterTemplate> dataSources = new ArrayList<ClusterTemplate>();
		RestCall caller = new RestCall();
		HttpURLConnection connection = caller.connect(endpoint + tenantId
				+ "/cluster-templates", null, "GET", token);
		try {
			if (connection.getResponseCode() != 200)
				return null;
			String JSONreponse = caller.getResponse(connection);
			connection.disconnect();
			List<JSONObject> dataSourcesJSON = JsonPath.read(JSONreponse,
					"$.cluster_templates[*]");

			for (JSONObject json : dataSourcesJSON) {
				dataSources.add(gson.fromJson(json.toJSONString(),
						ClusterTemplate.class));
			}
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return dataSources;
	}

	/**
	 * @param cluster_template_id
	 * 
	 *            This operation shows information about a specified Cluster
	 *            Template.
	 */
	public ClusterTemplate showCluster(String cluster_template_id) {
		RestCall caller = new RestCall();
		HttpURLConnection connection = caller.connect(endpoint + tenantId
				+ "/cluster-templates/" + cluster_template_id, null, "GET",
				token);
		try {
			if (connection.getResponseCode() != 200)
				return null;
			String JSONreponse = caller.getResponse(connection);
			connection.disconnect();

			return gson.fromJson(((JSONObject) JsonPath.read(JSONreponse,
					"$.cluster_template")).toJSONString(),
					ClusterTemplate.class);

		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}


	/**
	 * @param plugin_name
	 * @param hadoop_version
	 * @param nodeGroups
	 * @param neutron_management_network
	 * @param name
	 * @return This operation returns created Cluster Template.
	 */
	public ClusterTemplate createClusterTemplate(String plugin_name,
			String hadoop_version, NodeGroup[] nodeGroups,
			String neutron_management_network, String name) {
		RestCall caller = new RestCall();
		String nodeGroupsAsString = "";
		for (NodeGroup g : nodeGroups) {
			nodeGroupsAsString += "{\"name\": " + g.getName() + ", \"count\": "
					+ g.getCount() + ",\"node_group_template_id\": \""
					+ g.getNode_group_template_id() + "\"},";
		}
		String payload = "{    \"plugin_name\": \""
				+ plugin_name
				+ "\",    \"hadoop_version\": \""
				+ hadoop_version
				+ "\",    \"node_groups\": ["
				+ ((nodeGroupsAsString.length() > 0) ? nodeGroupsAsString
						.substring(0, nodeGroupsAsString.length() - 1) : "")
				+ "],    \"neutron_management_network\": \""
				+ neutron_management_network + "\",    \"name\": \"" + name
				+ "\",    \"cluster_configs\": {}}";

		HttpURLConnection connection = caller.connect(endpoint + tenantId
				+ "/cluster-templates", payload, "POST", token);
		try {
			if (connection.getResponseCode() != 202)
				return null;
			String JSONreponse = caller.getResponse(connection);
			connection.disconnect();
			return gson.fromJson(((JSONObject) JsonPath.read(JSONreponse,
					"$.cluster_template")).toJSONString(),
					ClusterTemplate.class);

		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * @param cluster_template_id
	 * 
	 *            Remove Cluster Template
	 */
	public boolean terminateCluster(String cluster_template_id) {
		RestCall caller = new RestCall();
		HttpURLConnection connection = caller.connect(endpoint + tenantId
				+ "/cluster-templates/" + cluster_template_id, null, "DELETE", token);
		try {
			if (connection.getResponseCode() == 204)
				return true;
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return false;
	}
}
